Skip to content

feat(workspace): add file-tree add-to-chat action#233

Open
DerrickBarra wants to merge 7 commits intodaggerhashimoto:masterfrom
GambitGamesLLC:slice/workspace-file-add-to-chat
Open

feat(workspace): add file-tree add-to-chat action#233
DerrickBarra wants to merge 7 commits intodaggerhashimoto:masterfrom
GambitGamesLLC:slice/workspace-file-add-to-chat

Conversation

@DerrickBarra
Copy link
Copy Markdown
Contributor

@DerrickBarra DerrickBarra commented Apr 4, 2026

Summary

Implements the next small stacked attachment slice after the canonical contract and composer simplification work by adding a workspace file-tree Add to chat action for existing workspace files.

In Plain English

This PR lets users add an existing workspace file to chat directly from the file tree.

That matters because if a file is already in the workspace, people should not have to re-upload it or jump through extra steps just to reference it in a conversation. The UI should let them point at the file they already have and bring it into chat cleanly.

This change adds that direct file-tree action while keeping the result inside the existing canonical workspace-reference flow. In short: faster file-to-chat handoff, with less friction and less duplication.

Stacking / dependency

This PR is intentionally stacked on top of:

If those earlier slices change materially, this PR will be revised accordingly.

What changed

  • adds a file-tree context-menu Add to chat action for existing workspace files
  • routes that action through the existing chat attachment handoff path
  • keeps the resulting attachment in the canonical workspace-reference flow
  • adds focused tests for file-only visibility/behavior

Deliberately not included

To keep this slice small and reviewable, it does not include:

  • directory-as-context behavior
  • optimization / derivative generation
  • unrelated composer UX changes beyond the existing stacked base
  • unrelated local/debug workflow surfaces

Verification

  • src/features/file-browser/FileTreePanel.test.tsx
  • src/features/chat/InputBar.test.tsx
  • tsc -p tsconfig.json --noEmit

Related to #232
Depends on #229
Depends on #231

Summary by CodeRabbit

  • New Features

    • Added "Add to chat" option to the file browser context menu, enabling users to quickly add files to their chat conversations.
  • Tests

    • Added tests for the "Add to chat" context menu functionality to ensure proper interaction behavior.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 4, 2026

📝 Walkthrough

Walkthrough

This PR implements a feature enabling users to add workspace file paths to chat from the file tree panel. The changes introduce an onAddToChat callback to FileTreePanel, expose an addWorkspacePath method on ChatPanel via imperative handle, and wire them together through the App component with a new context menu action.

Changes

Cohort / File(s) Summary
Chat Panel Interface & Implementation
src/features/chat/ChatPanel.tsx
Extended ChatPanelHandle interface with addWorkspacePath(path: string, kind: 'file' | 'directory') => Promise<void> method and implemented it via useImperativeHandle to delegate to inputBarRef.current?.addWorkspacePath(path, kind).
File Tree Panel Integration
src/features/file-browser/FileTreePanel.tsx
Added optional onAddToChat prop to FileTreePanelProps and integrated a new "Add to chat" context menu action (with Paperclip icon) that invokes the callback when clicked on file entries.
App Component Wiring
src/App.tsx
Added onAddToChat prop to both desktop and mobile FileTreePanel instances that forwards selected path and kind to chatPanelRef.current?.addWorkspacePath(path, kind) using optional chaining.
Test Coverage
src/features/file-browser/FileTreePanel.test.tsx
Added test suite for context menu "Add to chat" functionality, verifying callback invocation with correct path and kind parameters for files, and non-appearance for directories.

Sequence Diagram

sequenceDiagram
    actor User
    participant FileTree as FileTreePanel
    participant App
    participant ChatPanel
    participant InputBar as InputBar

    User->>FileTree: Right-click file in tree
    FileTree->>FileTree: Open context menu
    User->>FileTree: Click "Add to chat"
    FileTree->>App: onAddToChat(path, 'file')
    App->>ChatPanel: chatPanelRef.current?.addWorkspacePath(path, 'file')
    ChatPanel->>InputBar: inputBarRef.current?.addWorkspacePath(path, 'file')
    InputBar->>InputBar: Process and add path
    InputBar-->>ChatPanel: Promise resolved
    ChatPanel-->>App: Promise resolved
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • Issue #232: Directly addresses the requested "Add to chat" callback in FileTreePanel and addWorkspacePath method plumbing in ChatPanel that enables file paths to be forwarded to the chat system.

Possibly related PRs

  • PR #239: Also modifies src/features/chat/ChatPanel.tsx to add property plumbing (pathLinkPrefixes prop), sharing the same file and imperative handle infrastructure.

Poem

🐰 A hop through file trees, a path comes alive,
With paperclip icon, let chats all thrive!
From branch to input, the messages flow,
Adding to chat—watch the workspace grow! 📎✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main feature: adding a file-tree 'Add to chat' action for workspace files.
Description check ✅ Passed The PR description covers all required template sections with clear explanations, but the checklist and some optional elements are incomplete.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@DerrickBarra DerrickBarra force-pushed the slice/workspace-file-add-to-chat branch from 9a6ba09 to 0215573 Compare April 4, 2026 15:05
DerrickBarra added a commit to GambitGamesLLC/openclaw-nerve that referenced this pull request Apr 7, 2026
@daggerhashimoto daggerhashimoto marked this pull request as ready for review April 12, 2026 18:40
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/features/file-browser/FileTreePanel.tsx (1)

672-672: Use the existing trash helper for path classification consistency.

startsWith('.trash') can also match non-trash dotfiles (for example, .trash-notes.md). Consider using isTrashItemPath(menuPath) plus explicit .trash root checks.

Possible cleanup
-  const showAddToChat = Boolean(onAddToChat && menuEntry?.type === 'file' && !menuPath.startsWith('.trash') && menuPath !== '.trash');
+  const menuIsTrashRoot = menuPath === '.trash';
+  const menuIsTrashItem = isTrashItemPath(menuPath);
+  const showAddToChat = Boolean(onAddToChat && menuEntry?.type === 'file' && !menuIsTrashRoot && !menuIsTrashItem);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/features/file-browser/FileTreePanel.tsx` at line 672, Replace the ad-hoc
startsWith check with the project helper: update the showAddToChat condition
(where onAddToChat, menuEntry, menuPath are used) to use
isTrashItemPath(menuPath) for trash classification and still explicitly disallow
the root '.trash' path; i.e., remove startsWith('.trash') and use
!isTrashItemPath(menuPath) && menuPath !== '.trash' alongside the existing
onAddToChat and menuEntry?.type === 'file' checks so trash detection is
consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/features/file-browser/FileTreePanel.tsx`:
- Around line 800-803: The onClick handler currently drops the promise returned
by onAddToChat (called in FileTreePanel's onClick) which can lead to unhandled
rejections; wrap the call to onAddToChat in an async flow and handle failures
(either await in an async function or attach .catch) to surface errors and avoid
unhandled rejections — e.g., call an async wrapper that calls await
onAddToChat(menuEntry.path, 'file') inside try/catch and handle/report the error
(e.g., show a toast or log and restore UI state) after clearing
setContextMenu(null).

---

Nitpick comments:
In `@src/features/file-browser/FileTreePanel.tsx`:
- Line 672: Replace the ad-hoc startsWith check with the project helper: update
the showAddToChat condition (where onAddToChat, menuEntry, menuPath are used) to
use isTrashItemPath(menuPath) for trash classification and still explicitly
disallow the root '.trash' path; i.e., remove startsWith('.trash') and use
!isTrashItemPath(menuPath) && menuPath !== '.trash' alongside the existing
onAddToChat and menuEntry?.type === 'file' checks so trash detection is
consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b2d8fe68-7a46-48cd-a73d-7fe6b1565a21

📥 Commits

Reviewing files that changed from the base of the PR and between a5f7973 and a718c15.

📒 Files selected for processing (4)
  • src/App.tsx
  • src/features/chat/ChatPanel.tsx
  • src/features/file-browser/FileTreePanel.test.tsx
  • src/features/file-browser/FileTreePanel.tsx

Comment on lines +800 to +803
onClick={() => {
setContextMenu(null);
void onAddToChat?.(menuEntry.path, 'file');
}}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Handle async failures from onAddToChat instead of dropping them.

Line 802 intentionally discards the returned promise. If staging fails, this can become an unhandled rejection and a silent UX failure.

Proposed fix
-              onClick={() => {
-                setContextMenu(null);
-                void onAddToChat?.(menuEntry.path, 'file');
-              }}
+              onClick={async () => {
+                setContextMenu(null);
+                try {
+                  await onAddToChat?.(menuEntry.path, 'file');
+                } catch (err) {
+                  const message = err instanceof Error ? err.message : 'Failed to add file to chat';
+                  showToastForAgent(workspaceAgentId, { type: 'error', message }, 4500);
+                }
+              }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/features/file-browser/FileTreePanel.tsx` around lines 800 - 803, The
onClick handler currently drops the promise returned by onAddToChat (called in
FileTreePanel's onClick) which can lead to unhandled rejections; wrap the call
to onAddToChat in an async flow and handle failures (either await in an async
function or attach .catch) to surface errors and avoid unhandled rejections —
e.g., call an async wrapper that calls await onAddToChat(menuEntry.path, 'file')
inside try/catch and handle/report the error (e.g., show a toast or log and
restore UI state) after clearing setContextMenu(null).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants